﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using Microsoft.SqlServer;

namespace TweetRating
{
    public class Persistidor : IDisposable
    {
        private SqlConnection coneccionSql;

        #region Constructor
        public Persistidor()
        {
            string connectionString = Properties.Settings.Default.connectionString;
            coneccionSql = new SqlConnection(connectionString);
        }
        #endregion

        #region Metodos de escritura
        public void persistirPalabraClaveCalificada(PalabraClaveCalificada unaPalabra)
        {
            string palabra = (unaPalabra as IPalabraClave).obtenerPalabraClave();
            string intencion = unaPalabra.obtenerIntencion().ToString();

            string query = "INSERT INTO dbo.palabra (palabra, intencion) VALUES "
                         + "('" + palabra + "','" + intencion + "')";
            SqlCommand cmd = new SqlCommand(query, coneccionSql);

            coneccionSql.Open();
            cmd.ExecuteNonQuery();
            coneccionSql.Close();
        }
        public void persistirProgramaDeTV(ProgramaDeTV unPrograma)
        {
            string nombre = unPrograma.nombre;
            string dia = unPrograma.programacion.diaDeEmision.ToString();
            string horaDeInicio = unPrograma.programacion.horaDeInicio.ToString();
            string horaDeFinalizacion = unPrograma.programacion.horaDeFinalizacion.ToString();

            string query = "INSERT INTO dbo.programaDeTV (nombre, dia, horaDeInicio, horaDeFinalizacion) VALUES " 
                         + "('" + nombre + "','" + dia + "'," + horaDeInicio + "," + horaDeFinalizacion + ")";
            SqlCommand cmd = new SqlCommand(query, coneccionSql);

            coneccionSql.Open();
            cmd.ExecuteNonQuery();
            coneccionSql.Close();

            unPrograma.palabrasClave.ForEach(unaPalabraClave => 
                {
                    query = "INSERT INTO dbo.programaDeTV_palabraClave (nombre, palabraClave) VALUES "
                         + "('" + nombre + "','" + unaPalabraClave + "')";
                    cmd = new SqlCommand(query, coneccionSql);

                    coneccionSql.Open();
                    cmd.ExecuteNonQuery();
                    coneccionSql.Close();
                });
        }
        #endregion

        #region Metodos de lectura
        public List<PalabraClaveCalificada> leerPalabras()
        {
            List<PalabraClaveCalificada> palabrasGuardadas = new List<PalabraClaveCalificada>();

            string query = "SELECT * FROM dbo.palabra";
            SqlCommand cmd = new SqlCommand(query, coneccionSql);

            coneccionSql.Open();
            using (SqlDataReader dr = cmd.ExecuteReader())
            {
                while (dr.Read())
                {
                    string laPalabra = dr.GetString(dr.GetOrdinal("palabra")).Trim();
                    Intencion laIntencion = Enumeraciones.obtenerIntenciones().Find(unaIntencion => unaIntencion.ToString() == dr.GetString(dr.GetOrdinal("intencion")).Trim());
                    palabrasGuardadas.Add(new PalabraClaveCalificada(laIntencion, new PalabraClave(laPalabra)));
                }
                    
                dr.Close();
            }
            coneccionSql.Close();

            return palabrasGuardadas;
        }
        public List<ProgramaDeTV> solicitarProgramasDeTV()
        {
            List<ProgramaDeTV> losProgramasGuardados = new List<ProgramaDeTV>();

            string query = "SELECT * FROM dbo.programaDeTV";
            SqlCommand cmd = new SqlCommand(query, coneccionSql);

            coneccionSql.Open();
            using (SqlDataReader dr = cmd.ExecuteReader())
            {
                while (dr.Read())
                {
                    string nombre = dr.GetString(dr.GetOrdinal("nombre")).Trim();
                    DayOfWeek dia = Enumeraciones.obtenerDias().Find(unDia => unDia.ToString() == dr.GetString(dr.GetOrdinal("dia")).Trim());
                    int horaDeInicio = dr.GetInt32(dr.GetOrdinal("horaDeInicio"));
                    int horaDeFinalizacion = dr.GetInt32(dr.GetOrdinal("horaDeFinalizacion"));

                    Programacion laProgramacion = new Programacion(dia, new Hora(horaDeInicio), new Hora(horaDeFinalizacion));
                    ProgramaDeTV elPrograma = new ProgramaDeTV(nombre, laProgramacion, new List<IPalabraClave>());
                    losProgramasGuardados.Add(elPrograma);
                }
                dr.Close();
            }
            coneccionSql.Close();

            losProgramasGuardados.ForEach(unPrograma => this.agregarPalabrasClave(unPrograma));
            return losProgramasGuardados;
        }
        public List<ProgramaDeTV> solicitarProgramasDeTVEmitidosPorDiaYHorario(DayOfWeek diaBuscado, Hora desde, Hora hasta)
        {
            List<ProgramaDeTV> losProgramasGuardados = new List<ProgramaDeTV>();

            string query = "SELECT * FROM dbo.programaDeTV";
            SqlCommand cmd = new SqlCommand(query, coneccionSql);

            coneccionSql.Open();
            using (SqlDataReader dr = cmd.ExecuteReader())
            {
                while (dr.Read())
                {
                    string nombre = dr.GetString(dr.GetOrdinal("nombre")).Trim();
                    DayOfWeek dia = Enumeraciones.obtenerDias().Find(unDia => unDia.ToString() == dr.GetString(dr.GetOrdinal("dia")).Trim());
                    int horaDeInicio = dr.GetInt32(dr.GetOrdinal("horaDeInicio"));
                    int horaDeFinalizacion = dr.GetInt32(dr.GetOrdinal("horaDeFinalizacion"));

                    Programacion laProgramacion = new Programacion(dia, new Hora(horaDeInicio), new Hora(horaDeFinalizacion));
                    ProgramaDeTV elPrograma = new ProgramaDeTV(nombre, laProgramacion, new List<IPalabraClave>());
                    losProgramasGuardados.Add(elPrograma);
                }
                dr.Close();
            }
            coneccionSql.Close();

            losProgramasGuardados.ForEach(unPrograma => this.agregarPalabrasClave(unPrograma));
            return losProgramasGuardados.FindAll(unPrograma => unPrograma.programacion.diaDeEmision == diaBuscado && desde.hora <= unPrograma.programacion.horaDeInicio.hora && unPrograma.programacion.horaDeFinalizacion.hora <= hasta.hora);
        }
        #endregion

        #region Auxiliares
        private void agregarPalabrasClave(ProgramaDeTV unPrograma)
        {
            string query = "SELECT * FROM dbo.programaDeTV_palabraClave WHERE nombre = '" + unPrograma.nombre + "'";
            SqlCommand cmd = new SqlCommand(query, coneccionSql);

            coneccionSql.Open();
            using (SqlDataReader dr = cmd.ExecuteReader())
            {
                while (dr.Read())
                    unPrograma.palabrasClave.Add(new PalabraClave(dr.GetString(dr.GetOrdinal("palabraClave")).Trim()));
                dr.Close();
            }
            coneccionSql.Close();
        }
        #endregion

        #region Destructor
        void IDisposable.Dispose()
        {
            this.coneccionSql.Close();
        }
        #endregion
    }
}
